﻿namespace ProblemsSet
{
    public class Problem_17 : BaseProblem
    {
        #region Enums
        public static string[] Digits = new []{"" ,"One", "Two", "Three", "Four", 
            "Five" ,"Six", "Seven", "Eight", "Nine"};

        public static string[] Teens = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", 
            "Fifteen","Sixteen","Seventeen","Eighteen", "Nineteen"};

        public static string[] Tens = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", 
            "Seventy","Eighty", "Ninety"};

        public static string[] Bases = { "Thousand", "Lakh", "Crore" };

        #endregion

        public override object GetResult()
        {
            const int max = 1000;
            long count = 0;
            long rs = 0;
            for (var i = 1; i <= max; i++)
            {
                NumberToText(i, out count);
                rs += count;
            }
            return rs;
        }

        public static string NumberToText(long number, out long count) 
        {
            count = 0;
            if (number == 0)
            {
                count = 4;
                return "Zero";
            }

            var num = new long[4]; 
            var first = 0; 
            long u;
            long h;
            long t;
            var sb = new System.Text.StringBuilder(); 

            if (number < 0) 
            { 
                sb.Append("Minus "); 
                number = -number;
                count += 5;
            } 

            num[0] = number % 1000;
            num[1] = number / 1000; 
            num[2] = number / 100000; 
            num[1] = num[1] - 100 * num[2];
            num[3] = number / 10000000;
            num[2] = num[2] - 100 * num[3];

            for(var i = 3; i > 0 ; i--) 
            {
                if (num[i] == 0) continue;
                first = i; 
                break;
            } 

            for(var i = first ; i >= 0 ; i--) 
            { 
                if (num[i] == 0) continue; 
                u = num[i] % 10; 
                t = num[i] / 10; 
                h = num[i] / 100;
                t = t - 10 * h;

                if (h > 0)
                {
                    sb.Append(Digits[h] + " Hundred ");
                    count += 7 + Digits[h].Length;
                }

                if (u > 0 || t > 0)
                {
                    if (h > 0 || i == 0)
                    {
                        sb.Append(" and ");
                        count += 3;
                    }

                    switch (t)
                    {
                        case 0:
                            sb.Append(Digits[u]+" ");
                            count += Digits[u].Length;
                            break;
                        case 1:
                            sb.Append(Teens[u] + " ");
                            count += Teens[u].Length;
                            break;
                        default:
                            sb.Append(Tens[t - 2] + " " + Digits[u] + " ");
                            count += Tens[t - 2].Length + Digits[u].Length;
                            break;
                    }
                }

                if (i == 0) continue;
                sb.Append(Bases[i - 1] + " ");
                count += Bases[i-1].Length;
            }
            var rs = sb.ToString().Trim().Replace("  ", " ");
            while (rs.StartsWith("and"))
            {
                rs = rs.Remove(0, 3).Trim();
                count -= 3;
            }
            return rs; 
        } 

        public override string Problem
        {
            get
            {
                return @"If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?


NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of 'and' when writing out numbers is in compliance with British usage.";
            }
        }

        public override bool IsSolved
        {
            get
            {
                return true;
            }
        }

        public override object Answer
        {
            get
            {
                return 21124;
            }
        }

    }
}
